using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;

namespace Columbus.Converters
{
    /// <summary>
    /// Converts boolean to visibility
    /// </summary>
    public sealed class BooleanToVisibilityConverter : IValueConverter
    {
        /// <summary>
        /// Mode of conversion
        /// </summary>
        enum ConversionMode
        {
            /// <summary>
            /// Return 'Collapsed' if true is passed, otherwise return 'Visible'
            /// </summary>
            TrueMeansCollapsed,

            /// <summary>
            /// Return 'Collapsed' if false is passed, otherwise return 'Visible'
            /// </summary>
            FalseMeansCollapsed
        }

        /// <summary>
        /// Modifies the source data before passing it to the target for display in the UI.
        /// </summary>
        /// <param name="value">The source data being passed to the target.</param>
        /// <param name="targetType">The <see cref="T:System.Type"/> of data expected by the target dependency property.</param>
        /// <param name="parameter">An optional parameter to be used in the converter logic.</param>
        /// <param name="culture">The culture of the conversion.</param>
        /// <returns>
        /// The value to be passed to the target dependency property.
        /// </returns>
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var flag = false;
            if (value is bool)
            {
                flag = (bool)value;
            }
            else if (value is bool?)
            {
                var nullable = (bool?)value;
                flag = nullable.GetValueOrDefault();
            }
            if (parameter != null)
            {
                var direction = (ConversionMode)Enum.Parse(typeof(ConversionMode), (string)parameter, true);

                if (direction == ConversionMode.TrueMeansCollapsed)
                {
                    flag = !flag;
                }
            }
            return flag ? Visibility.Visible : Visibility.Collapsed;
        }

        /// <summary>
        /// Modifies the target data before passing it to the source object.  This method is called only in <see cref="F:System.Windows.Data.BindingMode.TwoWay"/> bindings.
        /// </summary>
        /// <param name="value">The target data being passed to the source.</param>
        /// <param name="targetType">The <see cref="T:System.Type"/> of data expected by the source object.</param>
        /// <param name="parameter">An optional parameter to be used in the converter logic.</param>
        /// <param name="culture">The culture of the conversion.</param>
        /// <returns>
        /// The value to be passed to the source object.
        /// </returns>
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var back = ((value is Visibility) && (((Visibility)value) == Visibility.Visible));
            if (parameter != null)
            {
                var direction = (ConversionMode)Enum.Parse(typeof(ConversionMode), (string)parameter, true);
                if (direction != ConversionMode.FalseMeansCollapsed)
                {
                    back = !back;
                }
            }
            return back;
        }
    }
}